package cn.enjoy.design.structure.proxy.config;

import cn.enjoy.design.structure.proxy.listener.FlowStateListener;
import cn.enjoy.design.structure.proxy.manager.FlowStateManager;
import cn.enjoy.design.structure.proxy.mapper.FlowFormMapper;
import cn.enjoy.design.structure.proxy.service.FlowService;
import cn.enjoy.design.structure.proxy.service.impl.FlowServiceImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.lang.NonNull;

/**
 * @author K
 * @date 2021-07-18 18:07
 */
@Configuration("WorkOrderBootstrap")
public class ProxyConfiguration implements BeanPostProcessor {

    private FlowStateManager stateManager = new FlowStateManager();


    /**
     * 注入状态管理器
     */
    @Bean
    @Primary
    public FlowStateManager flowStateManager() {
        return stateManager;
    }

    /**
     * 注入代理（相当于管理层，管理被代理的类）
     */
    @Bean
    public FlowProxyFactory flowOrderProxyFactory(FlowStateManager stateManager, DataSourceTransactionManager transactionManager) {
        return new FlowProxyFactory(stateManager, transactionManager);
    }

    /**
     * 注入被代理的类 FlowService的FlowServiceImpl实现类（相当于管理层下，被代理的类）
     */
    @Bean
    public FlowService flowService(FlowProxyFactory flowOrderProxyFactory, FlowFormMapper flowFormMapper) {
        return flowOrderProxyFactory.proxy(new FlowServiceImpl(flowFormMapper));
    }

    /**
     * Bean初始化后的回调，此处是判断Bean是否是FlowStateListener的实例，是的话就加入到stateManager
     */
    @Override
    public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {
        if (bean instanceof FlowStateListener) {
            stateManager.register((FlowStateListener<?>) bean);
        }
        return bean;
    }

}
